package org.dftproject.genesis.ui.presentation;

import org.dftproject.genesis.ui.pages.PageManager;
import org.dftproject.genesis.ui.pages.home.HomePage;
import org.dftproject.genesis.ui.pages.home.HomePageInput;
import org.dftproject.genesis.ui.presentation.stackcontrol.StackControl;
import org.dftproject.genesis.ui.presentation.stackcontrol.StackItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.presentations.IPresentablePart;
import org.eclipse.ui.presentations.IStackPresentationSite;
import org.eclipse.ui.presentations.StackDropResult;
import org.eclipse.ui.presentations.StackPresentation;

public class StackControlPresentation extends StackPresentation {

	private static final String DATAKEY_PART = "IPresentablePart";

	private final Composite parent;
	private final StackControl stackControl;

	public StackControlPresentation(Composite parent, IStackPresentationSite stackSite) {
		super(stackSite);
		this.parent = parent;

		stackControl = new StackControl(parent, SWT.NONE);
	}

	protected void createNewTab() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
		IWorkbenchPage workbenchPage = window.getActivePage();
		PageManager.getDefault().openPage(workbenchPage, new HomePageInput(), HomePage.ID, true, true);
	}

	@Override
	public void addPart(final IPresentablePart newPart, Object cookie) {
		final StackItem item = new StackItem(stackControl, SWT.NONE);
		item.setData(DATAKEY_PART, newPart);

		updateItem(newPart);

		newPart.addPropertyListener(new IPropertyListener() {

			public void propertyChanged(Object source, int propId) {
				updateItem(newPart);
			}

		});
	}

	protected void updateItem(final IPresentablePart part) {
		StackItem item = getStackItem(part);
		if (item == null)
			return;

		item.setText(part.getName());
		item.setImage(part.getTitleImage());

		resizeSelectedPart();
	}

	@Override
	public void dispose() {
		stackControl.dispose();
	}

	@Override
	public StackDropResult dragOver(Control currentControl, Point location) {
		return null;
	}

	@Override
	public Control getControl() {
		return stackControl;
	}

	@Override
	public Control[] getTabList(IPresentablePart part) {
		return null;
	}

	@Override
	public void removePart(IPresentablePart oldPart) {
		stackControl.closeStackItem(getStackItem(oldPart));
		resizeSelectedPart();
	}

	protected StackItem getStackItem(IPresentablePart part) {
		for (StackItem item : stackControl.getStackItems()) {
			if (item.getData(DATAKEY_PART) == part) {
				return item;
			}
		}
		return null;
	}

	@Override
	public void selectPart(IPresentablePart toSelect) {
		stackControl.setSelection(getStackItem(toSelect));

		for (IPresentablePart part : getSite().getPartList())
			part.setVisible(part == toSelect);

		resizeSelectedPart();
	}

	@Override
	public void setActive(int newState) {
	}

	@Override
	public void setBounds(Rectangle bounds) {
		stackControl.setBounds(bounds);
		resizeSelectedPart();
	}

	protected void resizeSelectedPart() {
		IPresentablePart part = getSite().getSelectedPart();
		if (part == null)
			return;

		StackItem item = getStackItem(part);
		if (item == null)
			return;

		Rectangle bounds = stackControl.getClientArea();

		bounds = item.getDisplay().map(stackControl, parent, bounds);

		part.setBounds(bounds);
	}

	@Override
	public void setState(int state) {
	}

	@Override
	public void setVisible(boolean isVisible) {
		stackControl.setVisible(isVisible);
		if (getSite().getSelectedPart() == null)
			return;
		getSite().getSelectedPart().setVisible(isVisible);
		if (getSite().getSelectedPart().getToolBar() != null)
			getSite().getSelectedPart().getToolBar().setVisible(isVisible);
	}

	@Override
	public void showPaneMenu() {
	}

	@Override
	public void showSystemMenu() {
	}

}
